import os.path
from typing import Any

import yaml
from injector import inject, singleton

from internal.core.tools.bean import Provider, ProviderItem, ToolsModel


@singleton
@inject
class ProviderFactory:
    provider_map: dict[str, Provider] = {}

    def __init__(self):
        self.init_provider()

    def get_provider(self, name: str) -> Provider:
        return self.provider_map.get(name)

    def get_provider_item(self, provider_name: str) -> ProviderItem:
        return self.provider_map.get(provider_name).provider_item

    def get_providers(self) -> list[Provider]:
        return [item for item in self.provider_map.values()]

    def get_provider_item_all(self) -> list[ProviderItem]:
        return [item.provider_item for item in self.provider_map.values()]

    def get_tool_bean(self, provider_name: str, tool_name: str) -> ToolsModel:
        provider = self.get_provider(provider_name)
        return provider.get_tool_bean(tool_name)

    def get_tool_fun(self, provider_name: str, tool_name: str) -> Any:
        provider = self.get_provider(provider_name)
        return provider.get_tool_fun(tool_name)()

    def init_provider(self):
        path = os.path.abspath(__file__)
        dir_path = os.path.dirname(path)
        path_join = os.path.join(dir_path, "providers.yaml")
        with open(path_join, encoding="utf-8") as f:
            yaml_data_arr = yaml.safe_load(f)
            for idx, item in enumerate(yaml_data_arr):
                self.provider_map[item.get("name")] = Provider(
                    name=item.get("name"),
                    position=idx + 1,
                    provider_item=item
                )
